//
//  MacroUtils.swift
//  MyMacro
//
//  Created by Entao on 2024/12/30.
//
import Foundation
import SwiftCompilerPlugin
import SwiftSyntax
import SwiftSyntaxBuilder
import SwiftSyntaxMacros

extension SwiftSyntax.AttributeSyntax {

    func argument(label: String) -> String? {
        return self.arguments?.as(LabeledExprListSyntax.self)?.first { $0.label?.text == label }?.expression.description
    }
}

extension SwiftSyntax.DeclSyntaxProtocol {
    var variableSpecifier: String? {
        guard let spec = self.as(VariableDeclSyntax.self)?.bindingSpecifier else { return nil }
        return spec.text
    }

    var variableName: String? {
        guard let binding = self.as(VariableDeclSyntax.self)?.bindings.first else { return nil }
        return binding.pattern.as(IdentifierPatternSyntax.self)?.identifier.text
    }
    var variableType: TypeInfo? {
        guard let binding = self.as(VariableDeclSyntax.self)?.bindings.first else { return nil }
        if let typeName = binding.typeAnnotation?.type.as(OptionalTypeSyntax.self)?.wrappedType.description {
            return TypeInfo(name: typeName, optional: true)
        }
        if let typeName = binding.typeAnnotation?.type.description {
            return TypeInfo(name: typeName, optional: false)
        }
        return nil
    }
}

class TypeInfo: CustomStringConvertible {
    let name: String
    let optional: Bool
    init(name: String, optional: Bool) {
        self.name = name
        self.optional = optional
    }
    var description: String {
        if optional {
            return name + "?"
        }
        return name
    }
}

extension String {
    var quoted: String {
        "\"\(self)\""
    }
}
public func println(_ items: Any?...) {
    for a in items {
        if let v = a ?? nil {
            print(v, terminator: " ")
        } else {
            print("nil", terminator: " ")
        }
    }
    print("")
}

public func error(message: String) throws -> Never {
    throw MacroError(message: message)
}

public final class MacroError: Error {
    let message: String
    public init(message: String) {
        self.message = message
    }
}
